package com.red.star.macalline.es.api.search;

import com.red.star.macalline.es.constant.Constant;
import com.red.star.macalline.es.utils.CheckUtil;
import org.elasticsearch.index.query.AbstractQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.index.query.QueryBuilders.queryStringQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

@RestController
@RequestMapping("/es/search")
public class SearchController {

	@Autowired
	private ElasticsearchTemplate elasticsearchTemplate;


	/**
	 * 单字符串模糊查询，默认排序。将从所有字段中查找包含传来的word分词后字符串的数据集
	 * @param className  要查询的类
	 * @param content   查询内容
	 * @param pageable
	 * @param queryType 0:查询列表,1:查询数量
	 * @return
	 * @throws ClassNotFoundException
	 */
	@RequestMapping("/allQuery")
	public Object allQuery(String className, String content, Integer queryType,@PageableDefault(sort = "optType", direction = Sort.Direction.DESC) Pageable pageable) throws ClassNotFoundException {
		if(CheckUtil.isEmpty(className) || CheckUtil.isEmpty(content)) {
			return "查询参数不正取";
		}
		AbstractQueryBuilder queryBuilder = queryStringQuery(content);
		return query(className,queryType,pageable,queryBuilder);
	}


	/**
	 * 单字段对某字符串模糊查询
	 * @param className 类名
	 * @param fieldName 根据某字段查询
	 * @param content
	 * @param queryType 0:查询列表,1:查询数量
	 * @param pageable
	 * @return
	 * @throws ClassNotFoundException
	 */
	@RequestMapping("/matchQuery")
	public Object singleMatchQuery(String className, String fieldName, String content, Integer queryType, @PageableDefault Pageable pageable) throws ClassNotFoundException {
		if(CheckUtil.isEmpty(className) || CheckUtil.isEmpty(fieldName) || CheckUtil.isEmpty(content)) {
			return "查询参数不正取";
		}
		AbstractQueryBuilder queryBuilder = matchQuery(fieldName,content);
		return query(className,queryType,pageable,queryBuilder);
	}


	/**
	 * term匹配，即不分词匹配，你传来什么值就会拿你传的值去做完全匹配
	 * @param className
	 * @param fieldName
	 * @param content
	 * @param queryType 0:查询列表,1:查询数量
	 * @param pageable
	 * @return
	 * @throws ClassNotFoundException
	 */
	@RequestMapping("/termQuery")
	public Object singleTermQuery(String className, String fieldName, String content, Integer queryType, @PageableDefault Pageable pageable) throws ClassNotFoundException {
		if(CheckUtil.isEmpty(className) || CheckUtil.isEmpty(fieldName) || CheckUtil.isEmpty(content)) {
			return "查询参数不正取";
		}
		AbstractQueryBuilder queryBuilder = termQuery(fieldName,content);
		return query(className,queryType,pageable,queryBuilder);
	}


	/**
	 * 综合所有查询
	 * @param className
	 * @param queryType
	 * @param pageable
	 * @param queryBuilder
	 * @return
	 * @throws ClassNotFoundException
	 */
	private Object query(String className, Integer queryType, Pageable pageable, AbstractQueryBuilder queryBuilder) throws ClassNotFoundException {
		Long startTime = System.currentTimeMillis();
		Object obj;
		SearchQuery searchQuery;
		if(CheckUtil.isEmpty(queryType)) {
			searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder).withPageable(pageable).build();
			obj = elasticsearchTemplate.queryForList(searchQuery, Class.forName(Constant.CLASS_PACKAGE_PATH+className));
		}else {
			searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder).build();
			obj = elasticsearchTemplate.count(searchQuery,Class.forName(Constant.CLASS_PACKAGE_PATH+className));
		}
		Long time = System.currentTimeMillis() - startTime;
		System.out.println("执行时间(毫秒):"+time);
		return obj;
	}

}
